package geotransform.tools;

import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.lang.reflect.Array;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import sun.misc.Sort;

import com.sun.org.apache.bcel.internal.generic.NEWARRAY;

import geotransform.*;
import geotransform.coords.*;
import geotransform.datum.*;
import geotransform.ellipsoids.*;
import geotransform.transforms.*;


public class AtualizarCadastro {
	//Listas dos elementos de entrada
	public ArrayList<ElementoEDP> ips;
	public ArrayList<ElementoEDP> postes;
	public ArrayList<ElementoEDP> atualizados;
	public ArrayList<ElementoColeta> coletas;
	
	//Listas dos elementos	de saida
	public ArrayList<ElementoEDP> outputIps;
	public ArrayList<ElementoEDP> outputPostes;
	public ArrayList<ElementoColeta> outputColetas;
	
	
	public AtualizarCadastro(String ipsFileName, String postesFileName, ArrayList< ArrayList<String> > coletasList) throws InvalidObjectException, FileNotFoundException, IOException, Exception  {
	
		ips = new ArrayList<ElementoEDP>();
		postes = new ArrayList<ElementoEDP>();
		coletas = new ArrayList<ElementoColeta>();

		outputIps = new ArrayList<ElementoEDP>();
		outputPostes = new ArrayList<ElementoEDP>();
		outputColetas = new ArrayList<ElementoColeta>();
		
		
		for(ArrayList<String> coletasData: coletasList){
			ElementoColeta e = new ElementoColeta(coletasData);
			coletas.add(e);
		}
		
		BufferedReader ipReader = new BufferedReader(new FileReader(ipsFileName));
		BufferedReader posteReader = new BufferedReader(new FileReader(postesFileName));
		

		String line;
		
		while((line = ipReader.readLine())!= null) {
			ElementoEDP e = new ElementoEDP(line, 'i', 24); //adicionar zona da bandeirante
			ips.add(e);
		}
		ipReader.close();
		
		while((line = posteReader.readLine())!= null) {
			ElementoEDP e = new ElementoEDP(line, 'p', 24);  //adicionar zona da bandeirante
			postes.add(e);
		}
		posteReader.close();

	}
	
	public class Neighbors {
		public int cadastro, coleta;
		double d;//dist

		public Neighbors(int col, int cad, double D) {
			cadastro = cad;
			coleta = col;
			d = D;
		}
	}
	
	class compareNeighbor implements Comparator<Neighbors>{
		@Override
		public int compare(Neighbors o1, Neighbors o2) {
			return o1.d == o2.d? 0 : (o1.d < o2.d? -1 : 1);
		}
	}
	
	public void match() throws Exception{
		int nC = coletas.size();
        int nI = ips.size();
        int nP = postes.size();
        
        int[] matchC, matchI, matchP;
        matchC = new int[nC];
        matchI = new int[nI];
        matchP = new int[nP];
      
        ArrayList<Neighbors> neighborhood = new ArrayList<Neighbors>();
        
        //ips
        for(int u = 0; u<nC; u++){
        	for(int v = 0; v<nI; v++){
        		Utm_Coord_3d coordC = (coletas.get(u)).getCoordUTM();
        		Utm_Coord_3d coordI = (ips.get(v)).getCoordUTM();
        		
        		double dist = Math.sqrt((coordC.x-coordI.x)*(coordC.x-coordI.x) + (coordC.y-coordI.y)*(coordC.y-coordI.y));
        		if(dist <= 15){
        			neighborhood.add(new Neighbors(u,v,dist));
        		}
        	}
        }
        compareNeighbor c = new compareNeighbor();
        Collections.sort(neighborhood,c);
        for(Neighbors n: neighborhood){
        	if(matchC[n.coleta]==0 && matchI[n.cadastro]==0){
        		matchC[n.coleta] = matchI[n.cadastro] = 1;
        		
            	ElementoColeta col = coletas.get(n.coleta);
            	ElementoEDP oldIp = ips.get(n.cadastro);
            	
            	String newX, newY, newLampada;
            	newX = String.format("%d",(int)(col.getCoordUTM().x*100));
            	newY = String.format("%d",(int)(col.getCoordUTM().y*100));
            	newLampada = col.classe;
            	
            	ElementoEDP atualIp = new ElementoEDP(oldIp, newX, newY, newLampada);
            	outputIps.add(atualIp);
        	}
        }
        neighborhood.clear();
        
        //postes
        for(int u = 0; u<nC; u++){
        	for(int v = 0; v<nP; v++){
        		if(matchC[u] == 0){
        			Utm_Coord_3d coordC = (coletas.get(u)).getCoordUTM();
            		Utm_Coord_3d coordP = (postes.get(v)).getCoordUTM();
            		
            		double dist = Math.sqrt((coordC.x-coordP.x)*(coordC.x-coordP.x) + (coordC.y-coordP.y)*(coordC.y-coordP.y));
            		if(dist <= 15){
            			neighborhood.add(new Neighbors(u,v,dist));
            		}
        		}
        	}
        }
        Collections.sort(neighborhood,c);
        for(Neighbors n: neighborhood){
        	if(matchC[n.coleta]==0 && matchP[n.cadastro]==0){
        		matchC[n.coleta] = matchP[n.cadastro] = 1;
        		
            	ElementoColeta col = coletas.get(n.coleta);
            	ElementoEDP oldPoste = postes.get(n.cadastro);
            	
            	String newX, newY, newLampada;
            	newX = String.format("%d",(int)(col.getCoordUTM().x*100));
            	newY = String.format("%d",(int)(col.getCoordUTM().y*100));
            	newLampada = col.classe;
            	
            	ElementoEDP atualPoste = new ElementoEDP(oldPoste, newX, newY, newLampada);
            	outputPostes.add(atualPoste);
        	}
        }
        neighborhood.clear();
        
        //novos
        for(int u = 0; u<nC; u++){
        	if(matchC[u] == 0){
        			matchC[u] = 1;
        			
        			ElementoColeta col = coletas.get(u);
        			outputColetas.add(col);
        	}
        }
	}
	
	
	public void exportKml(String outDir) throws IOException, Exception{
		DateFormat dateformat = new SimpleDateFormat("dd-MM-yyyy_HH-mm-ss");
		Date date = new Date();
		
		String c, a;
		String codigo = dateformat.format(date);
		c = outDir + System.getProperty("file.separator") + "mapa-cadastro_" + codigo + ".kml";
		a = outDir + System.getProperty("file.separator") + "mapa-atualizacao_" + codigo + ".kml";
		
		BufferedWriter cadastro = new BufferedWriter(new FileWriter(c));

		cadastro.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n<Document>\n\t<name>Cadastro.kml</name>\n\t<Style id=\"sh_info-i\">\n\t\t<IconStyle>\n\t\t\t<color>ff00ffff</color>\n\t\t\t<scale>1.4</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/info-i.png</href>\n\t\t\t</Icon>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<Style id=\"sh_info-i0\">\n\t\t<IconStyle>\n\t\t\t<color>ff00ff00</color>\n\t\t\t<scale>1.4</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/info-i.png</href>\n\t\t\t</Icon>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<StyleMap id=\"msn_info-i\">\n\t\t<Pair>\n\t\t\t<key>normal</key>\n\t\t\t<styleUrl>#sn_info-i</styleUrl>\n\t\t</Pair>\n\t\t<Pair>\n\t\t\t<key>highlight</key>\n\t\t\t<styleUrl>#sh_info-i</styleUrl>\n\t\t</Pair>\n\t</StyleMap>\n\t<Style id=\"sn_info-i\">\n\t\t<IconStyle>\n\t\t\t<color>ff00ffff</color>\n\t\t\t<scale>1.2</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/info-i.png</href>\n\t\t\t</Icon>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<StyleMap id=\"msn_info-i0\">\n\t\t<Pair>\n\t\t\t<key>normal</key>\n\t\t\t<styleUrl>#sn_info-i0</styleUrl>\n\t\t</Pair>\n\t\t<Pair>\n\t\t\t<key>highlight</key>\n\t\t\t<styleUrl>#sh_info-i0</styleUrl>\n\t\t</Pair>\n\t</StyleMap>\n\t<Style id=\"sn_info-i0\">\n\t\t<IconStyle>\n\t\t\t<color>ff00ff00</color>\n\t\t\t<scale>1.2</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/info-i.png</href>\n\t\t\t</Icon>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<Folder>\n\t\t<name>Cadastro</name>\n\t\t<open>1</open>\n");


		cadastro.write("\t\t<Folder>\n\t\t\t<name>cIps</name>\n");
		for(ElementoEDP e : ips){
			String id = e.id;
			String classe = e.lampada;
			Gdc_Coord_3d g = e.getCoordGeo();
			double lat = g.latitude;
			double lon = g.longitude;
			cadastro.write("\t\t\t<Placemark>\n\t\t\t\t<name>i-"+id+"</name>\n\t\t\t\t<description>"+classe+"</description>\n\t\t\t\t<styleUrl>#msn_info-i0</styleUrl>\n\t\t\t\t<Point>\n\t\t\t\t\t<coordinates>"+lon+","+lat+"</coordinates>\n\t\t\t\t</Point>\n\t\t\t</Placemark>\n");
		}
		cadastro.write("\t\t</Folder>\n");


		cadastro.write("\t\t<Folder>\n\t\t\t<name>cPostes</name>\n");
		for(ElementoEDP e : postes){
			String id = e.id;
			String classe = e.lampada;
			Gdc_Coord_3d g = e.getCoordGeo();
			double lat = g.latitude;
			double lon = g.longitude;
			cadastro.write("\t\t\t<Placemark>\n\t\t\t\t<name>p-"+id+"</name>\n\t\t\t\t<description>"+classe+"</description>\n\t\t\t\t<styleUrl>#msn_info-i</styleUrl>\n\t\t\t\t<Point>\n\t\t\t\t\t<coordinates>"+lon+","+lat+"</coordinates>\n\t\t\t\t</Point>\n\t\t\t</Placemark>\n");
		}
		cadastro.write("\t\t</Folder>\n");


		cadastro.write("\t</Folder>\n</Document>\n</kml>");

		cadastro.close();


		BufferedWriter atualizacao = new BufferedWriter(new FileWriter(a));

		atualizacao.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n<Document>\n\t<name>Atualizacao.kml</name>\n\t<StyleMap id=\"msn_arrow-reverse\">\n\t\t<Pair>\n\t\t\t<key>normal</key>\n\t\t\t<styleUrl>#sn_arrow-reverse1</styleUrl>\n\t\t</Pair>\n\t\t<Pair>\n\t\t\t<key>highlight</key>\n\t\t\t<styleUrl>#sh_arrow-reverse1</styleUrl>\n\t\t</Pair>\n\t</StyleMap>\n\t<StyleMap id=\"msn_arrow-reverse0\">\n\t\t<Pair>\n\t\t\t<key>normal</key>\n\t\t\t<styleUrl>#sn_arrow-reverse</styleUrl>\n\t\t</Pair>\n\t\t<Pair>\n\t\t\t<key>highlight</key>\n\t\t\t<styleUrl>#sh_arrow-reverse</styleUrl>\n\t\t</Pair>\n\t</StyleMap>\n\t<StyleMap id=\"msn_arrow-reverse1\">\n\t\t<Pair>\n\t\t\t<key>normal</key>\n\t\t\t<styleUrl>#sn_arrow-reverse0</styleUrl>\n\t\t</Pair>\n\t\t<Pair>\n\t\t\t<key>highlight</key>\n\t\t\t<styleUrl>#sh_arrow-reverse0</styleUrl>\n\t\t</Pair>\n\t</StyleMap>\n\t<Style id=\"sh_arrow-reverse\">\n\t\t<IconStyle>\n\t\t\t<color>ff00ffff</color>\n\t\t\t<scale>1.4</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/arrow-reverse.png</href>\n\t\t\t</Icon>\n\t\t\t<hotSpot x=\"54\" y=\"42\" xunits=\"pixels\" yunits=\"pixels\"/>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<Style id=\"sn_arrow-reverse\">\n\t\t<IconStyle>\n\t\t\t<color>ff00ffff</color>\n\t\t\t<scale>1.2</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/arrow-reverse.png</href>\n\t\t\t</Icon>\n\t\t\t<hotSpot x=\"54\" y=\"42\" xunits=\"pixels\" yunits=\"pixels\"/>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<Style id=\"sn_arrow-reverse0\">\n\t\t<IconStyle>\n\t\t\t<color>ff00ff00</color>\n\t\t\t<scale>1.2</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/arrow-reverse.png</href>\n\t\t\t</Icon>\n\t\t\t<hotSpot x=\"54\" y=\"42\" xunits=\"pixels\" yunits=\"pixels\"/>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<Style id=\"sh_arrow-reverse0\">\n\t\t<IconStyle>\n\t\t\t<color>ff00ff00</color>\n\t\t\t<scale>1.4</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/arrow-reverse.png</href>\n\t\t\t</Icon>\n\t\t\t<hotSpot x=\"54\" y=\"42\" xunits=\"pixels\" yunits=\"pixels\"/>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<Style id=\"sn_arrow-reverse1\">\n\t\t<IconStyle>\n\t\t\t<color>ff0000ff</color>\n\t\t\t<scale>1.2</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/arrow-reverse.png</href>\n\t\t\t</Icon>\n\t\t\t<hotSpot x=\"54\" y=\"42\" xunits=\"pixels\" yunits=\"pixels\"/>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<Style id=\"sh_arrow-reverse1\">\n\t\t<IconStyle>\n\t\t\t<color>ff0000ff</color>\n\t\t\t<scale>1.4</scale>\n\t\t\t<Icon>\n\t\t\t\t<href>http://maps.google.com/mapfiles/kml/shapes/arrow-reverse.png</href>\n\t\t\t</Icon>\n\t\t\t<hotSpot x=\"54\" y=\"42\" xunits=\"pixels\" yunits=\"pixels\"/>\n\t\t</IconStyle>\n\t\t<ListStyle>\n\t\t</ListStyle>\n\t</Style>\n\t<Folder>\n\t\t<name>Atualizacao</name>\n\t\t<open>1</open>\n");


		atualizacao.write("\t\t<Folder>\n\t\t\t<name>aIps</name>\n");
		for(ElementoEDP e: outputIps){
			String id = e.id;
			String classe = e.lampada;
			Gdc_Coord_3d g = e.getCoordGeo();
			double lat = g.latitude;
			double lon = g.longitude;
			atualizacao.write("\t\t\t<Placemark>\n\t\t\t\t<name>i-"+id+"</name>\n\t\t\t\t<description>"+classe+"</description>\n\t\t\t\t<styleUrl>#msn_arrow-reverse1</styleUrl>\n\t\t\t\t<Point>\n\t\t\t\t\t<coordinates>"+lon+","+lat+"</coordinates>\n\t\t\t\t</Point>\n\t\t\t</Placemark>\n");
		}
		atualizacao.write("\t\t</Folder>\n");


		atualizacao.write("\t\t<Folder>\n\t\t\t<name>aPostes</name>\n");
		for(ElementoEDP e: outputPostes){
			String id = e.id;
			String classe = e.lampada;
			Gdc_Coord_3d g = e.getCoordGeo();
			double lat = g.latitude;
			double lon = g.longitude;
			atualizacao.write("\t\t\t<Placemark>\n\t\t\t\t<name>p-"+id+"</name>\n\t\t\t\t<description>"+classe+"</description>\n\t\t\t\t<styleUrl>#msn_arrow-reverse0</styleUrl>\n\t\t\t\t<Point>\n\t\t\t\t\t<coordinates>"+lon+","+lat+"</coordinates>\n\t\t\t\t</Point>\n\t\t\t</Placemark>\n");
		}
		atualizacao.write("\t\t</Folder>\n");


		atualizacao.write("\t\t<Folder>\n\t\t\t<name>aNovos</name>\n");
		for(ElementoColeta e: outputColetas){
			String classe = e.classe;
			Gdc_Coord_3d g = e.getCoordGeo();
			double lat = g.latitude;
			double lon = g.longitude;
			atualizacao.write("\t\t\t<Placemark>\n\t\t\t\t<name>n-"+classe+"</name>\n\t\t\t\t<description>"+classe+"</description>\n\t\t\t\t<styleUrl>#msn_arrow-reverse</styleUrl>\n\t\t\t\t<Point>\n\t\t\t\t\t<coordinates>"+lon+","+lat+"</coordinates>\n\t\t\t\t</Point>\n\t\t\t</Placemark>\n");
		}
		atualizacao.write("\t\t</Folder>\n");


		atualizacao.write("\t</Folder>\n</Document>\n</kml>");

		atualizacao.close();
	}
	
	public ArrayList<ElementoEDP> getOutputIps() {
		return outputIps;
	}

	public ArrayList<ElementoEDP> getOutputPostes() {
		return outputPostes;
	}

	public ArrayList<ElementoColeta> getOutputColetas() {
		return outputColetas;
	}
}
